package com.cskaoyan.order.service.impl;

import com.cskaoyan.mall.commons.exception.BizException;
import com.cskaoyan.mall.commons.exception.ExceptionProcessorUtils;
import com.cskaoyan.mall.order.constant.OrderRetCode;
import com.cskaoyan.order.biz.TransOutboundInvoker;
import com.cskaoyan.order.biz.context.AbsTransHandlerContext;
import com.cskaoyan.order.biz.factory.OrderProcessPipelineFactory;
import com.cskaoyan.order.constant.OrderConstants;
import com.cskaoyan.order.dal.entitys.Order;
import com.cskaoyan.order.dal.entitys.OrderItem;
import com.cskaoyan.order.dal.entitys.Stock;
import com.cskaoyan.order.dal.persistence.OrderItemMapper;
import com.cskaoyan.order.dal.persistence.OrderMapper;
import com.cskaoyan.order.dal.persistence.OrderShippingMapper;
import com.cskaoyan.order.dal.persistence.StockMapper;
import com.cskaoyan.order.dto.*;
import com.cskaoyan.order.service.OrderCoreService;
import com.cskaoyan.order.utils.GlobalIdGeneratorUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class OrderCoreServiceImpl implements OrderCoreService {


	@Autowired
    OrderMapper orderMapper;

	@Autowired
    OrderItemMapper orderItemMapper;

	@Autowired
    OrderShippingMapper orderShippingMapper;

	@Autowired
    OrderProcessPipelineFactory orderProcessPipelineFactory;

	@Autowired
    StockMapper stockMapper;


	/**
	 * 创建订单的处理流程
	 *
	 * @param request
	 * @return
	 */
	@Override
	public CreateOrderResponse createOrder(CreateOrderRequest request) {
		CreateOrderResponse response = new CreateOrderResponse();
		try {
			// 参数校验
			request.requestCheck();

			//创建pipeline对象
			TransOutboundInvoker invoker = orderProcessPipelineFactory.build(request);

			//启动pipeline
			invoker.start(); //启动流程（pipeline来处理）

			//获取处理结果
			AbsTransHandlerContext context = invoker.getContext();

			//把处理结果转换为response
			response = (CreateOrderResponse) context.getConvert().convertCtx2Respond(context);
		} catch (Exception e) {
			log.error("OrderCoreServiceImpl.createOrder Occur Exception :" + e);
			e.printStackTrace();
			ExceptionProcessorUtils.wrapperHandlerException(response, e);
		}
		return response;
	}

	@Transactional
	@Override
	public CancelOrderResponse cancelOrder(CancelOrderRequest request) {
		CancelOrderResponse response = new CancelOrderResponse();
		try {
			request.requestCheck();
			// 	取消订单
			Order order = new Order();
			String orderId = request.getOrderId();
			order.setOrderId(orderId);
			order.setStatus(OrderConstants.ORDER_STATUS_TRANSACTION_CANCEL);
			order.setUpdateTime(new Date());
			int affectedRows = orderMapper.updateByPrimaryKeySelective(order);
			if(affectedRows != 1){
				log.error("无效订单号或者数据库异常！");
				throw new BizException("无效订单号或者数据库异常！");
			}
			// 释放锁定库存
			boolean flag = releaseLockCountByOrderId(orderId);
			if(!flag){
				log.error("释放锁定库存失败！");
				throw new BizException("释放锁定库存失败！");
			}
			response.setCode(OrderRetCode.SUCCESS.getCode());
			response.setMsg(OrderRetCode.SUCCESS.getMessage());
		}catch (Exception e){
			log.error("OrderCoreServiceImpl.cancelOrder Occur Exception :" + e);
			e.printStackTrace();
			ExceptionProcessorUtils.wrapperHandlerException(response, e);
		}
		return response;
	}

	@Transactional
	@Override
	public DeleteOrderResponse deleteOrder(DeleteOrderRequest request) {
		DeleteOrderResponse response = new DeleteOrderResponse();
		Order order = new Order();
		try {
			request.requestCheck();

			String orderId = request.getOrderId();
			order.setOrderId(orderId);
			Order queryOrder = orderMapper.selectByPrimaryKey(order);
			Integer status = queryOrder.getStatus();
			int affectedRows = orderMapper.deleteByPrimaryKey(order);
			if(affectedRows != 1){
				throw new BizException("无效订单号或者数据库异常！");
			}
			if(status == 0){
				// 释放锁定库存
				boolean flag = releaseLockCountByOrderId(orderId);
				if(!flag){
					log.error("释放锁定库存失败！");
					throw new BizException("释放锁定库存失败！");
				}
			}
			response.setCode(OrderRetCode.SUCCESS.getCode());
			response.setMsg(OrderRetCode.SUCCESS.getMessage());
		}catch (Exception e){
			log.error("OrderCoreServiceImpl.deleteOrder Occur Exception :" + e);
			e.printStackTrace();
			ExceptionProcessorUtils.wrapperHandlerException(response, e);
		}

		return response;
	}

	/***
	 * 根据OrderId释放锁定库存
 	 * @param orderId
	 * @return boolean
	 * @author LY
	 * @since 2022/06/21 22:10
	 */
	@Transactional
	public boolean releaseLockCountByOrderId(String orderId){

		try {

			// 查询订单商品详细信息
			List<OrderItem> orderItems = orderItemMapper.queryByOrderId(orderId);

			// 获取订单商品Id
			List<Long> productIds = orderItems.stream().map(u -> u.getItemId()).sorted().collect(Collectors.toList());

			// 按照商品ID查询库存并锁定库存
			List<Stock> stockList = stockMapper.findStocksForUpdate(productIds);

			// 遍历订单商品，释放锁定库存
			for (OrderItem orderItem : orderItems) {
				Long productId = orderItem.getItemId();
				Integer productNum = orderItem.getNum();
				Stock stock = new Stock();
				stock.setItemId(productId);
				stock.setLockCount(-productNum);
				stock.setStockCount(+productNum.longValue());
				stockMapper.updateStock(stock);
			}
			return true;
		}catch (Exception e){
			log.error("OrderCoreServiceImpl.releaseLockCountByOrderId Occur Exception :" + e);
			e.printStackTrace();
			return false;
		}
	}
}
